/*
 * Lanzador.cpp
 *
 * Se encarga de lanzar las instancias de los planetas.
 *
 *  Created on: 25/02/2010
 *      Author: San Martín, Matías I.
 */



#ifndef LANZADOR_H_
#define LANZADOR_H_

#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>

#include "Planeta.h"

#include "../../Common/Registry.h"
#include "../../Common/Mensajes/DatosMensajeFactory.h"

#include "../../Infraestructura/DirectorioImpl.h"

#include "../../../Middleware/Comunicaciones/MiddlewareCliente.h"
#include "../../../Middleware/EnPlaneta/MsjEmisor.h"
#include "../../../Middleware/EnPlaneta/MsjReceptorApp.h"
#include "../../../Middleware/EnPlaneta/MsjReceptorMid.h"

#include "../../../Framework/Shared/sem.h"
#include "../../../Framework/Shared/shptr.h"
#include "../../../Framework/IO/log.h"

namespace aplicacion {
namespace planeta {

class Lanzador {

public:
	static const char OPT_TERMINAR = '0';
	static const char OPT_NUEVO_PLANETA = '1';
	static const char OPT_NUEVO_UNIVERSO = '2';

private:

	static Semaphore _semAccesoInfoPipe;
	static Semaphore _semLeyendoDatos;
	static t_sharedRegistro _datosRegitro;
	static InformacionPlaneta _infoPlanetaAlt;

	static pid_t _pidMsjReceptor;
	static pid_t _pidPlaneta;

public:

	/**
	 * Inicia el Lanzador.
	 * Permite al usuario lanzar nuevos planetas asociados a universos.
	 */
	void run();

private:

	/**
	 * Inicia un proceso planeta a la espectativa de la llegada del aviso
	 * de inicio del juego y que luego inicia le ejecucion de la aplicacion
	 * planeta
	 */
	pid_t iniciarPlaneta(const InformacionPlaneta& info);

	/**
	 * Permite elegir al usuario entre las posibles acciones a llevar a cabo
	 */
	char elegirAccion();

	/**
	 * Guarda en el log la informacion pertinente
	 */
	void logearInfoPlaneta(const InformacionPlaneta& info);

	/**
	 * Permite al usuario ingresar la configuracion inicial del planeta
	 */
	InformacionPlaneta definirPlaneta();

	void crearPlaneta(const InformacionCreacionUniverso& u);
	void crearUniverso();

	/**
	 * Permite al usuario ingresar la configuracion inicial del universo
	 */
	InformacionCreacionUniverso definirUniverso();

	/**
	 * Devuelve el universo elegido
	 */
	InformacionCreacionUniverso elegirUniverso();

	/**
	 * Inicializa los recursos compartidos
	 */
	void inicializarRecursos();

	/**
	 * Libera los recursos compartidos
	 */
	void liberarRecursos();

	/**
	 * Interrumpe la ejecución del planeta y del receptor
	 */
	void terminar();

	/**
	 * Termina la ejecucion del proceso logueando el mensaje de error
	 */
	void abortar (const std::string& errorMsj);

	/**
	 * Crea un proceso que ejecuta el receptor de mensajes.
	 * Devuelve el pid del proceso lanzado
	 */
	pid_t lanzarMsjReceptor();

	/**
	 * Inicializa el middleware base
	 */
	void iniciarMiddleware();

};

} //namespace planeta
} //namespace aplicacion

#endif /* LANZADOR_H_ */
